import React, { useState, useEffect, memo, useMemo } from 'react';
import _ from 'lodash';
import { nanoid } from 'nanoid';
import { Button, Empty, Form, Spin, TreeSelect, Select, Card, message } from 'antd';
import DebounceWrapper from '@/components/DebounceWrapper';
import DraggableModal from '@/components/DraggableModal';
import { DeleteOutlined, PlusOutlined } from '@ant-design/icons';
import {
  fetchUserDepartmentIds,
  fetchUserJobWithDepartment,
  fetchUserRoleWithDepartment,
  updateUserAscription,
} from '@/services/system/user';
import {
  fetchDepartmentList,
  fetchJobListWithDepartmentRelation,
  fetchRoleListWithDepartmentRelation,
} from '@/services/system/department';
import { formatTree } from '@/utils/utils';
import styles from './distributionDialog.less';

const randomLength = 12;
const layout = {
  labelCol: { span: 6 },
  wrapperCol: { span: 16 },
};
const DebounceButton = DebounceWrapper(Button);
const getValuesFromTree = (tree) => {
  const valueList = [];
  const loop = (list = []) => {
    if (list && list.length) {
      _.forEach(list, ({ value, children }) => {
        valueList.push(value);
        loop(children);
      });
    }
  };
  loop(tree);
  return valueList;
};

const FormCube = memo(
  ({
    id,
    index,
    userId,
    organId,
    formIds,
    organTreeOptions,
    changeOrganId,
    updateFieldsValue,
    deleteItem,
  }) => {
    const [jobList, setJobList] = useState([]);
    const [roleList, setRoleList] = useState([]);
    const [loading, setLoading] = useState(false);

    // 获取机构关联的岗位选项
    const getJobRelationList = async (organId) => {
      try {
        const res = await fetchJobListWithDepartmentRelation({ organId });
        return _.isArray(res)
          ? _.map(
              _.filter(res, (item) => _.isPlainObject(item)),
              ({ postName, id }) => ({ label: postName, value: id }),
            )
          : [];
      } catch (e) {
        return [];
      }
    };
    // 获取机构关联的角色选项
    const getRoleRelationList = async (organId) => {
      try {
        const res = await fetchRoleListWithDepartmentRelation({ organId });
        return _.isArray(res)
          ? _.map(
              _.filter(res, (item) => _.isPlainObject(item)),
              ({ roleName, id }) => ({ label: roleName, value: id }),
            )
          : [];
      } catch (e) {
        return [];
      }
    };
    // 获取用户机构下已选择的岗位
    const getUserJobIds = async (params) => {
      try {
        const res = await fetchUserJobWithDepartment(params);
        return _.isArray(res) ? res : [];
      } catch (e) {
        return [];
      }
    };
    // 获取用户机构下已选择的
    const getUserRoleIds = async (params) => {
      try {
        const res = await fetchUserRoleWithDepartment(params);
        return _.isArray(res) ? res : [];
      } catch (e) {
        return [];
      }
    };

    // 修改更新或初始化选项
    const initSelectOpts = (organId) => {
      return new Promise((resolve) => {
        Promise.all([getJobRelationList(organId), getRoleRelationList(organId)]).then((result) => {
          const [jobData, roleData] = result;
          setJobList(jobData);
          setRoleList(roleData);
          resolve(result);
        });
      });
    };
    // 获取选择值
    const getSelectValue = (params) => {
      return new Promise((resolve) => {
        Promise.all([getUserJobIds(params), getUserRoleIds(params)]).then((result) => {
          resolve(result);
        });
      });
    };

    // 初始化
    useEffect(() => {
      if (organId) {
        setLoading(true);
        Promise.all([initSelectOpts(organId), getSelectValue({ organId, userId })]).then(
          (result) => {
            const [selectOptList, selectValueList] = result;
            const [jobData, roleData] = selectOptList;
            const [jobValue, roleValue] = selectValueList;
            const postIds = _.filter(
              jobValue,
              (val) => _.findIndex(jobData, ({ value }) => value === val) > -1,
            );
            const roleIds = _.filter(
              roleValue,
              (val) => _.findIndex(roleData, ({ value }) => value === val) > -1,
            );
            updateFieldsValue({ [`${id}-postIds`]: postIds, [`${id}-roleIds`]: roleIds });
            setLoading(false);
          },
        );
      }
    }, []);

    return (
      <Card
        size="small"
        style={{ marginTop: '16px' }}
        title={`机构${index + 1}`}
        extra={
          index ? (
            <DebounceButton size="small" type="link" icon={<DeleteOutlined />} onClick={deleteItem}>
              删除
            </DebounceButton>
          ) : null
        }
      >
        <Spin spinning={loading} tip="加载中..">
          <Form.Item
            name={`${id}-organId`}
            label={'所属机构'}
            tooltip={'支持选择组织机构中任意一节点'}
            initialValue={undefined}
            dependencies={_.map(formIds, (id) => `${id}-organId`)}
            rules={[
              ({ getFieldsValue }) => ({
                validator: (rules, val) => {
                  const organIds = _.values(
                    _.pickBy(
                      getFieldsValue(),
                      (v, k) => /\-organId$/.test(k) && k !== `${id}-organId`,
                    ),
                  );
                  if (_.includes(organIds, val)) {
                    return Promise.reject(new Error('所属机构不能重复选择'));
                  }
                  return Promise.resolve();
                },
              }),
            ]}
          >
            <TreeSelect
              allowClear
              treeData={organTreeOptions}
              placeholder="请选择机构"
              onChange={(v) => {
                changeOrganId(v || undefined);
                if (v) {
                  setLoading(true);
                  initSelectOpts(v).then(() => {
                    setLoading(false);
                  });
                } else {
                  setJobList([]);
                  setRoleList([]);
                }
              }}
            />
          </Form.Item>
          <Form.Item
            name={`${id}-postIds`}
            label={'所属岗位'}
            tooltip={'岗位支持多选'}
            initialValue={[]}
          >
            <Select allowClear mode="multiple" options={jobList} placeholder="请选择岗位" />
          </Form.Item>
          <Form.Item
            name={`${id}-roleIds`}
            label={'角色'}
            tooltip={'角色支持多选'}
            initialValue={[]}
          >
            <Select allowClear mode="multiple" options={roleList} placeholder="请选择角色" />
          </Form.Item>
        </Spin>
      </Card>
    );
  },
  (prevProps, nextProps) =>
    prevProps.index === nextProps.index &&
    _.isEqual(prevProps.formIds, nextProps.formIds) &&
    prevProps.organTreeOptions === nextProps.organTreeOptions,
);

export default ({ visible, options, closeModal }) => {
  const [form] = Form.useForm();
  const { nickName, realName, userId } = options;
  const [organTreeOptions, setOrganTreeOptions] = useState([]);
  const [initialLoading, setInitialLoading] = useState(true);

  const [formListWithDepartmentId, setFormListWithDepartmentId] = useState([]);
  const [selectedDepartmentLoadingId, setSelectedDepartmentLoadingId] = useState('');

  const [actionLoading, setActionLoading] = useState(false);

  const validOrganIds = useMemo(() => getValuesFromTree(organTreeOptions), [organTreeOptions]);

  // 获取机构节点选项
  const getOrganTree = async () => {
    try {
      const res = await fetchDepartmentList({ size: -1, current: 1 });
      return _.isArray(res)
        ? formatTree(res, ({ organName, id }) => ({ key: id, value: id, title: organName }))
        : [];
    } catch (e) {
      return [];
    }
  };
  // 获取当前用户已关联的机构
  const getOrganIdsByUser = async (userId) => {
    try {
      const res = await fetchUserDepartmentIds({ userId });
      return _.isArray(res) ? res : [];
    } catch (e) {
      return [];
    }
  };

  // 初始化
  useEffect(() => {
    getOrganTree().then((tree) => {
      setOrganTreeOptions(tree);
      setInitialLoading(false);
    });
  }, []);
  useEffect(() => {
    if (!initialLoading) {
      if (visible) {
        const nextDepartmentLoadingId = nanoid(randomLength);
        setSelectedDepartmentLoadingId(nextDepartmentLoadingId);
        getOrganIdsByUser(userId).then((list) => {
          let validDataFetch;
          setSelectedDepartmentLoadingId((currentId) => {
            if (currentId === nextDepartmentLoadingId) {
              validDataFetch = true;
              return '';
            }
            return currentId;
          });
          if (validDataFetch) {
            // 排除无效的机构id（机构可能已被删除）
            const validList = _.filter(list, (id) => _.includes(validOrganIds, id));
            if (_.isEmpty(validList)) {
              setFormListWithDepartmentId([{ id: nanoid(randomLength) }]);
            } else {
              const currentFormListWithDepId = _.map(validList, (organId) => ({
                organId,
                id: nanoid(randomLength),
              }));
              setFormListWithDepartmentId(currentFormListWithDepId);
              form.setFieldsValue(
                _.assign(
                  {},
                  ..._.map(currentFormListWithDepId, ({ organId, id }) => ({
                    [`${id}-organId`]: organId,
                  })),
                ),
              );
            }
          }
        });
        return;
      }
    }
    form.resetFields();
    setFormListWithDepartmentId([]);
    setSelectedDepartmentLoadingId('');
  }, [visible, initialLoading]);

  const handleCancel = () => {
    if (!actionLoading) {
      closeModal();
    }
  };
  const handleConfirm = () => {
    setActionLoading(true);
    form
      .validateFields()
      .then((values) => {
        const userOrganDataRelationList = [];
        const groupKeys = _.groupBy(_.keys(values), (k) => k.substring(0, randomLength + 1));
        _.forEach(_.keys(groupKeys), (key) => {
          userOrganDataRelationList.push(
            _.assign(
              {},
              ..._.map(groupKeys[key], (valueKey) => ({
                [valueKey.substring(randomLength + 1)]: values[valueKey],
              })),
            ),
          );
        });
        const params = {
          userId,
          userOrganDataRelationList: _.filter(
            userOrganDataRelationList,
            ({ organId }) => !!organId,
          ),
        };
        // console.log('入参', params);
        updateUserAscription(params)
          .then(() => {
            closeModal();
            setActionLoading(false);
            message.success(`${nickName || realName || '用户'}机构、岗位、角色更新成功`);
          })
          .catch(() => {
            setActionLoading(false);
          });
      })
      .catch(() => {
        setActionLoading(false);
      });
  };

  return (
    <DraggableModal
      title={`更新用户机构、岗位、角色${
        nickName || realName ? '（' + (nickName || realName) + '）' : ''
      }`}
      visible={visible}
      onCancel={handleCancel}
      bodyStyle={{ paddingTop: 0 }}
      footer={[
        <DebounceButton key="cancel" disabled={actionLoading} onClick={closeModal}>
          取消
        </DebounceButton>,
        <DebounceButton
          key="confirm"
          type="primary"
          loading={actionLoading}
          onClick={handleConfirm}
        >
          提交
        </DebounceButton>,
      ]}
    >
      <Spin spinning={initialLoading || !!selectedDepartmentLoadingId} tip={'初始化..'}>
        <Form {...layout} form={form} name="user-department-job-role">
          {formListWithDepartmentId.length ? (
            formListWithDepartmentId.map(({ id, organId }, index) => (
              <FormCube
                key={id}
                id={id}
                index={index}
                userId={userId}
                organId={organId}
                formIds={_.map(formListWithDepartmentId, 'id')}
                organTreeOptions={organTreeOptions}
                changeOrganId={(nextOrganId) => {
                  let isChange;
                  setFormListWithDepartmentId((prevList) => {
                    const nextList = [...prevList];
                    const index = _.findIndex(nextList, ({ id: currentId }) => currentId === id);
                    if (index > -1) {
                      isChange = nextList[index].organId !== nextOrganId;
                      nextList[index] = _.assign({}, nextList[index], {
                        organId: nextOrganId || undefined,
                      });
                    }
                    return nextList;
                  });
                  if (isChange) {
                    form.setFieldsValue({ [`${id}-postIds`]: [], [`${id}-roleIds`]: [] });
                  }
                }}
                updateFieldsValue={(val) => {
                  form.setFieldsValue(val);
                }}
                deleteItem={() => {
                  setFormListWithDepartmentId((prevList) => {
                    const nextList = [...prevList];
                    const index = _.findIndex(nextList, ({ id: currentId }) => currentId === id);
                    if (index > -1) {
                      nextList.splice(index, 1);
                    }
                    return nextList;
                  });
                }}
              />
            ))
          ) : (
            <Empty description="暂无数据" />
          )}
        </Form>
        <DebounceButton
          block
          type="dashed"
          icon={<PlusOutlined />}
          className={styles.addButton}
          onClick={() => {
            setFormListWithDepartmentId((prevList) => {
              const nextList = [...prevList, { id: nanoid(randomLength) }];
              return nextList;
            });
          }}
        >
          添加机构
        </DebounceButton>
      </Spin>
    </DraggableModal>
  );
};
